﻿using System;

namespace Hvam.SharePoint.Search.Language.Parsers
{
    internal static class ParserCombinators
    {
        public static Parser<U> Select<T, U>(this Parser<T> parser, Func<T, U> convert)
        {
            return 
                input =>
                       {
                           var result = parser(input);
                           if (result.IsSuccess())
                           {
                               var success = (Success<T>) result;

                               return new Success<U>(convert(success.Result), result.Input);
                           }
                           return new Failure<U>(result.Input);
                       };
        }

        public static Parser<V> SelectMany<T, U, V>(
            this Parser<T> parser,
            Func<T, Parser<U>> selector,
            Func<T, U, V> projector)
        {
            return input =>
            {
                var res = parser(input);
                if (res.IsFailure())
                {
                    return new Failure<V>(res.Input);
                }

                var success = (Success<T>) res;

                var val = success.Result;
                var res2 = selector(val)(success.Input);
                
                if (res2.IsFailure())
                {
                    return new Failure<V>(res2.Input);
                }

                var success2 = (Success<U>)res2;

                return new Success<V>(projector(val, success2.Result), success2.Input);
            };
        }
    }
}